"""
数据缓存模块

负责缓存热点数据到内存，提高数据访问速度
"""

import time
from functools import lru_cache
from typing import Dict, Any, Optional, List
import pandas as pd
from ..core import unified_logger


class DataCache:
    """数据缓存管理器"""
    
    def __init__(self, cache_size: int = 10000):
        """
        初始化数据缓存管理器
        
        Args:
            cache_size: 缓存大小
        """
        self.cache_size = cache_size
        self.logger = unified_logger.get_logger('data_cache')
        self._cache: Dict[str, Dict[str, Any]] = {}
        self._access_times: Dict[str, float] = {}
    
    def _generate_cache_key(self, exchange: str, market_type: str, 
                           symbol: str, period: str) -> str:
        """生成缓存键"""
        return f"{exchange}:{market_type}:{symbol}:{period}"
    
    def put(self, exchange: str, market_type: str, symbol: str, 
            period: str, data: pd.DataFrame) -> None:
        """
        存储数据到缓存
        
        Args:
            exchange: 交易所名称
            market_type: 市场类型
            symbol: 交易对
            period: 时间周期
            data: 数据DataFrame
        """
        try:
            cache_key = self._generate_cache_key(exchange, market_type, symbol, period)
            
            # 检查缓存大小限制
            if len(self._cache) >= self.cache_size:
                self._evict_oldest()
            
            # 存储数据和元信息
            self._cache[cache_key] = {
                'data': data.copy(),
                'timestamp': time.time(),
                'size': len(data)
            }
            self._access_times[cache_key] = time.time()
            
            self.logger.debug(f"缓存数据: {cache_key}, 大小: {len(data)}")
            
        except Exception as e:
            self.logger.error(f"缓存数据失败: {e}")
    
    def get(self, exchange: str, market_type: str, symbol: str, 
            period: str) -> Optional[pd.DataFrame]:
        """
        从缓存获取数据
        
        Args:
            exchange: 交易所名称
            market_type: 市场类型
            symbol: 交易对
            period: 时间周期
            
        Returns:
            缓存的数据DataFrame，如果不存在返回None
        """
        try:
            cache_key = self._generate_cache_key(exchange, market_type, symbol, period)
            
            if cache_key in self._cache:
                # 更新访问时间
                self._access_times[cache_key] = time.time()
                
                cached_item = self._cache[cache_key]
                self.logger.debug(f"命中缓存: {cache_key}")
                
                return cached_item['data'].copy()
            
            return None
            
        except Exception as e:
            self.logger.error(f"获取缓存数据失败: {e}")
            return None
    
    def _evict_oldest(self) -> None:
        """淘汰最旧的缓存项"""
        if not self._access_times:
            return
        
        # 找到最旧的缓存项
        oldest_key = min(self._access_times.keys(), 
                        key=lambda k: self._access_times[k])
        
        # 删除缓存项
        if oldest_key in self._cache:
            del self._cache[oldest_key]
        if oldest_key in self._access_times:
            del self._access_times[oldest_key]
        
        self.logger.debug(f"淘汰缓存: {oldest_key}")
    
    def invalidate(self, exchange: str, market_type: str, 
                  symbol: str, period: str) -> None:
        """
        使缓存失效
        
        Args:
            exchange: 交易所名称
            market_type: 市场类型
            symbol: 交易对
            period: 时间周期
        """
        try:
            cache_key = self._generate_cache_key(exchange, market_type, symbol, period)
            
            if cache_key in self._cache:
                del self._cache[cache_key]
            if cache_key in self._access_times:
                del self._access_times[cache_key]
            
            self.logger.debug(f"使缓存失效: {cache_key}")
            
        except Exception as e:
            self.logger.error(f"使缓存失效失败: {e}")
    
    def clear(self) -> None:
        """清空所有缓存"""
        self._cache.clear()
        self._access_times.clear()
        self.logger.info("清空所有缓存")
    
    def get_cache_stats(self) -> Dict[str, Any]:
        """
        获取缓存统计信息
        
        Returns:
            缓存统计信息
        """
        try:
            total_size = sum(item['size'] for item in self._cache.values())
            
            return {
                'total_items': len(self._cache),
                'total_size': total_size,
                'cache_limit': self.cache_size,
                'usage_ratio': len(self._cache) / self.cache_size if self.cache_size > 0 else 0
            }
            
        except Exception as e:
            self.logger.error(f"获取缓存统计失败: {e}")
            return {}
    
    def is_cached(self, exchange: str, market_type: str, 
                  symbol: str, period: str) -> bool:
        """
        检查数据是否已缓存
        
        Args:
            exchange: 交易所名称
            market_type: 市场类型
            symbol: 交易对
            period: 时间周期
            
        Returns:
            是否已缓存
        """
        cache_key = self._generate_cache_key(exchange, market_type, symbol, period)
        return cache_key in self._cache